<?php

class Database_Mysql {

  protected $_connect;

  public function __construct($config) {

    $this->_connect = mysql_pconnect($config['host'], $config['username'], $config['password']);
    mysql_select_db($config['dbname'], $this->_connect);
  }

  protected function _query($sql) {
    Logger::write($sql);
    return mysql_query($sql, $this->_connect);
  }

  protected function _insert($pk, $table, $fields, $data, $mode = '') {
    $d = array();
    foreach ($fields as $f) {
      $v = @$data[$f];
      if ($v == NULL) {
        $d[$f] = 'NULL';
      } else {
        $d[$f] = "'" . mysql_escape_string($v) . "'";
      }
    }
    $sql = sprintf('INSERT %s INTO %s (`%s`) VALUES (%s);', $mode, $table, implode('`,`', $fields), implode(" , ", $d));
    $result = $this->_query($sql);
    return $result;
  }

  protected function quote($value) {
    if ($value === NULL) {
      return 'NULL';
    } else {
      return "'" . mysql_escape_string($value) . "'";
    }
  }

  protected function _update($pk, $table, $fields, $data) {
    $kv = array();
    foreach ($fields as $f) {
      if ($f != $pk) {
        $kv[] = sprintf('`%s`=%s', $f, $this->quote(@$data[$f]));
      }
    }
    $identity = $this->quote(@$data[$pk]);

    $sql = sprintf('UPDATE %s SET %s WHERE `%s` =  %s', $table, implode(',', $kv), $pk, $identity);
    return $this->_query($sql);
  }

  public function update($model) {
    return $this->_update($model->pk(), $model->table(), $model->fields(), $model->data());
  }

  /**
   * @param data $data
   * @param model $model 
   */
  public function insert($model, $data = NULL) {
    if (is_string($model)) {
      $model = new $model($data);
    } elseif (is_array($data)) {
      $model->setData($data);
    }
    return $this->_insert($model->pk(), $model->table(), $model->fields(), $model->data());
  }

  public function lastInsertId() {
    return mysql_insert_id();
  }

  public function _find($table, $value, $field) {
    $sql = "SELECT * from $table where $field =  '$value' limit 1;";
    if (($result = $this->_query($sql)) != NULL) {
      return mysql_fetch_assoc($result);
    }
    return NULL;
  }

  public function find($model, $value, $field = NULL) {
    $model = $this->getModel($model);
    if ($field == NULL) {
      $field = $model->pk();
    }
    return $this->_find($model->table(), $value, $field);
  }

  public function getModel($model, $data = NULL) {
    if (is_string($model)) {
      return new $model($data);
    }
    return $model;
  }

}
